<template>
  <el-tag v-if="displayText" :type="tagType" :size="size" :effect="effect" :round="round" :closable="closable"
    :disable-transitions="disableTransitions" :hit="hit" :color="color" @close="handleClose" @click="handleClick">
    {{ displayText }}
  </el-tag>
  <span v-else class="crud-tag__empty">{{ emptyText }}</span>
</template>

<script setup lang="ts">
import { computed } from 'vue'

/**
 * 标签类型
 */
type TagType = 'primary' | 'success' | 'warning' | 'danger' | 'info'

/**
 * 组件属性接口
 */
interface Props {
  /** 标签值 */
  value?: string | number | boolean
  /** 标签类型映射 */
  typeMap?: Record<string, TagType>
  /** 标签文本映射 */
  textMap?: Record<string, string>
  /** 默认标签类型 */
  defaultType?: TagType
  /** 标签尺寸 */
  size?: 'large' | 'default' | 'small'
  /** 标签主题 */
  effect?: 'dark' | 'light' | 'plain'
  /** 是否圆形 */
  round?: boolean
  /** 是否可关闭 */
  closable?: boolean
  /** 是否禁用渐变动画 */
  disableTransitions?: boolean
  /** 是否有边框描边 */
  hit?: boolean
  /** 背景色 */
  color?: string
  /** 空值时显示的文本 */
  emptyText?: string
}

/**
 * 组件事件接口
 */
interface Emits {
  /** 关闭事件 */
  (e: 'close'): void
  /** 点击事件 */
  (e: 'click', event: MouseEvent): void
}

/**
 * Props 定义
 */
const props = withDefaults(defineProps<Props>(), {
  defaultType: 'primary',
  size: 'default',
  effect: 'light',
  round: false,
  closable: false,
  disableTransitions: false,
  hit: false,
  emptyText: '-'
})

/**
 * 事件定义
 */
const emit = defineEmits<Emits>()

/**
 * 标签值的字符串表示
 */
const valueString = computed(() => {
  if (props.value === null || props.value === undefined) return ''
  return String(props.value)
})

/**
 * 显示文本
 */
const displayText = computed(() => {
  if (!valueString.value) return ''

  // 如果有文本映射，优先使用映射的文本
  if (props.textMap && props.textMap[valueString.value]) {
    return props.textMap[valueString.value]
  }

  return valueString.value
})

/**
 * 标签类型
 */
const tagType = computed(() => {
  if (!valueString.value) return props.defaultType

  // 如果有类型映射，使用映射的类型
  if (props.typeMap && props.typeMap[valueString.value]) {
    return props.typeMap[valueString.value]
  }

  return props.defaultType
})

/**
 * 处理关闭事件
 */
const handleClose = (): void => {
  emit('close')
}

/**
 * 处理点击事件
 * @param event - 鼠标点击事件
 */
const handleClick = (event: MouseEvent): void => {
  emit('click', event)
}
</script>

<style lang="scss" scoped>
.crud-tag__empty {
  color: #c0c4cc;
  font-size: 14px;
}
</style>
